উদাহরণ সহ JWT Authentication এবং Authorization

Java Technologies - স্প্রিং সিকিউরিটি (Spring Security) - Spring Security এবং JWT (JSON Web Token)
210

JWT (JSON Web Token) হল একটি স্ট্যান্ডার্ড টোকেন-ভিত্তিক প্রমাণীকরণ এবং অনুমোদনের পদ্ধতি, যেখানে একটি কমপ্যাক্ট এবং সেলফ-কনটেইনড টোকেন ব্যবহার করা হয়। Spring Security-তে JWT Authentication এবং Authorization কনফিগার করার জন্য নিচে একটি স্টেপ-বাই-স্টেপ উদাহরণ দেওয়া হলো।


1. JWT-এর মূল বৈশিষ্ট্য

  • Stateless Authentication: সার্ভার সেশন মেইনটেইন করে না, বরং ক্লায়েন্ট-সাইডে টোকেন সংরক্ষণ করে।
  • Self-contained Token: টোকেনে সমস্ত তথ্য এনকোড করা থাকে (যেমন ইউজার আইডি, রোল)।
  • Security: টোকেনটি সাইন করা থাকে যাতে এটি পরিবর্তন করা না যায়।

2. প্রজেক্ট ডিপেন্ডেন্সি

Spring Boot এবং JWT লাইব্রেরি যুক্ত করতে pom.xml বা build.gradle-এ ডিপেন্ডেন্সি যোগ করুন।

Maven Dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

Gradle Dependency

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'io.jsonwebtoken:jjwt:0.9.1'

3. JWT Token তৈরি এবং যাচাই করার ক্লাস

i. JWT Utility ক্লাস

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class JwtUtil {

    private String secretKey = "mySecretKey";
    private long expirationTime = 1000 * 60 * 60; // 1 hour

    // টোকেন তৈরি
    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expirationTime))
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
    }

    // টোকেন থেকে ইউজারনেম বের করা
    public String extractUsername(String token) {
        return getClaims(token).getSubject();
    }

    // টোকেন এক্সপায়ার্ড কিনা যাচাই
    public boolean isTokenExpired(String token) {
        return getClaims(token).getExpiration().before(new Date());
    }

    // টোকেন যাচাই
    public boolean validateToken(String token, String username) {
        return (username.equals(extractUsername(token)) && !isTokenExpired(token));
    }

    // প্রাইভেট মেথড: Claims বের করা
    private Claims getClaims(String token) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
    }
}

4. Spring Security Configuration

i. Security Config ক্লাস

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
                .antMatchers("/authenticate", "/register").permitAll() // Public endpoints
                .anyRequest().authenticated(); // Others require authentication
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password(passwordEncoder().encode("password")).roles("USER")
            .and()
            .withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

5. Authentication Controller

i. Token প্রদান করার জন্য Controller

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/authenticate")
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping
    public String generateToken(@RequestBody AuthRequest authRequest) {
        try {
            Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
            );
            return jwtUtil.generateToken(authRequest.getUsername());
        } catch (Exception e) {
            throw new RuntimeException("Invalid username/password");
        }
    }
}

// DTO for authentication request
class AuthRequest {
    private String username;
    private String password;

    // Getters and Setters
}

6. JWT Filter

i. JWT Token যাচাই করার জন্য Filter

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class JwtFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
        String authorizationHeader = request.getHeader("Authorization");

        String token = null;
        String username = null;

        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            token = authorizationHeader.substring(7);
            username = jwtUtil.extractUsername(token);
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            if (jwtUtil.validateToken(token, username)) {
                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                        username, null, new ArrayList<>());
                authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }
        chain.doFilter(request, response);
    }
}

7. Filter Configuration

i. Filter Spring Security Config-এ যুক্ত করা

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtFilter jwtFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
                .antMatchers("/authenticate").permitAll()
                .anyRequest().authenticated()
                .and()
            .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

8. Test Endpoints

Public Endpoint:

@GetMapping("/public")
public String publicEndpoint() {
    return "This is a public endpoint";
}

Secured Endpoint:

@GetMapping("/secured")
public String securedEndpoint() {
    return "This is a secured endpoint";
}

JWT ব্যবহার করার প্রক্রিয়া

  1. /authenticatePOST রিকোয়েস্ট পাঠিয়ে টোকেন জেনারেট করুন।
  2. টোকেনটি প্রতিটি সিকিউরড রিকোয়েস্টে Authorization HeaderBearer <token> আকারে পাঠান।
  3. সিকিউরড এন্ডপয়েন্টে এক্সেস পান।

উপসংহার

Spring Security-তে JWT Authentication এবং Authorization ইমপ্লিমেন্ট করলে আপনার অ্যাপ্লিকেশন stateless এবং নিরাপদ হয়। উপরোক্ত উদাহরণটি ব্যবহার করে আপনি সহজেই একটি JWT-ভিত্তিক Authentication সিস্টেম তৈরি করতে পারবেন।

Content added By
Promotion
NEW SATT AI এখন আপনাকে সাহায্য করতে পারে।

Are you sure to start over?

Loading...